#include <nxos.h>

NX_PRIVATE NX_U32 threadEntry(void * arg)
{
    NX_Printf("thread %d running...\n", NX_ThreadGetCurrentId());
    while (1)
    {
    }
    return 0;
}

NX_PRIVATE void test_signal_threads(void)
{
    NX_Solt thread = NX_SOLT_INVALID_VALUE;
    int i;
    NX_Error err;

    for (i = 0; i < 32; i++)
    {
        thread = NX_ThreadCreate(NX_NULL, threadEntry, NX_NULL, 0);
        err = NX_ErrorGet();
        NX_Printf("create thread %d state %s\n", thread, NX_ErrorToString(err));
    }
    threadEntry(NX_NULL);
}

NX_PRIVATE int handleCount = 0;

NX_PRIVATE void SignalHandler(NX_SignalInfo * info)
{
    NX_Printf("signal handler %d, %p, %d\n", info->signal, info->signalValue, info->tid);
    handleCount++;
    NX_Printf("signal handle count: %d\n", handleCount);
}

NX_PRIVATE void test_signal_handler(void)
{
    NX_SignalAttr attr;
    NX_Error err;
    attr.handler = SignalHandler;
    err = NX_SignalSetAttr(NX_SIGNAL_TERMINATE, &attr);
    
    NX_Printf("signal set attr:%s\n", NX_ErrorToString(err));
    while (1)
    {
        /* code */
    }
    
}

NX_PRIVATE void test_signal_block(void)
{
    NX_Error err;
    
    err = NX_SignalControl(NX_SIGNAL_TERMINATE, NX_SIGNAL_TERMINATE, NX_SIGNAL_CMD_BLOCK);
    NX_Printf("signal control:%s\n", NX_ErrorToString(err));
    
    while (1)
    {
        /* code */
    }
}

NX_PRIVATE void test_signal_unblock(void)
{
    NX_Error err;
    
    err = NX_SignalControl(NX_SIGNAL_TERMINATE, NX_SIGNAL_TERMINATE, NX_SIGNAL_CMD_BLOCK);
    NX_Printf("signal control:%s\n", NX_ErrorToString(err));
    err = NX_SignalControl(NX_SIGNAL_TERMINATE, NX_SIGNAL_TERMINATE, NX_SIGNAL_CMD_UNBLOCK);
    NX_Printf("signal control:%s\n", NX_ErrorToString(err));
    
    while (1)
    {
        /* code */
    }
}

NX_PRIVATE void test_signal_set_get_attr(void)
{
    NX_Error err;
    NX_SignalAttr attr;
    NX_SignalAttr oldAttr;

    err = NX_SignalInitAttr(&attr, SignalHandler, 0);
    NX_Printf("signal init attr:%s\n", NX_ErrorToString(err));
    err = NX_SignalGetAttr(NX_SIGNAL_TERMINATE, &oldAttr);
    NX_Printf("signal get attr:%s handler:%p\n", NX_ErrorToString(err), oldAttr.handler);
    err = NX_SignalSetAttr(NX_SIGNAL_TERMINATE, &attr);
    NX_Printf("signal set attr:%s\n", NX_ErrorToString(err));
    err = NX_SignalGetAttr(NX_SIGNAL_TERMINATE, &oldAttr);
    NX_Printf("signal get attr:%s handler:%p\n", NX_ErrorToString(err), oldAttr.handler);
    while (1)
    {
        /* code */
    }
}

NX_Error TEST_Signal(char *cmdline)
{
    test_signal_set_get_attr();
    test_signal_threads();
    test_signal_handler();
    test_signal_block();
    test_signal_unblock();
    return NX_EOK;
}
